package cn.zk.single.server;

import cn.zk.single.domain.Message;
import cn.zk.single.domain.User;
import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * handler
 *
 * ChannelInboundHandlerAdapter 是 ChannelInboundHandlerAdapter的子类
 */
public class NettyGroupChatHandler extends SimpleChannelInboundHandler<String> {

    // 采用map管理channel k:address, v:Channel
    Map<String, Channel> channelMap = new HashMap<String, Channel>();

    // 时间格式化
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 读取客户端的数据 -> 找到对应人发消息
     * 自己发的消息要做区分
     * @param channelHandlerContext
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {
        // 输出mes检查
        System.out.println(msg);

        Channel sender = channelHandlerContext.channel();
        Message message = (Message) JSON.parse(msg);
        // 接收人
        Channel receiver = channelMap.get(message.getReceiver());
        System.out.println(receiver.remoteAddress().toString());
        receiver.writeAndFlush("==>"+sdf.format(new Date())
                +" ["+sender.remoteAddress()+"]"+" : "+message.getMessage());

        sender.writeAndFlush("==>"+sdf.format(new Date())
                +" [自己]"+" : "+message.getMessage());
    }

    /**
     * 客户端建立连接时回触发该方法 -> 客户端上线
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        // 加入到channelGroup中管理
        channelMap.put(channel.remoteAddress().toString(),channel);
        // 回复客户端上线
        channel.writeAndFlush("==>"+sdf.format(new Date())
                +" ["+channel.remoteAddress()+"]"+" 上线！");
    }

    /**
     * 客户端断开连接时回触发该方法 -> 客户端下线
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        // 加入到channelGroup中管理
        //channelMap.remove(channel.remoteAddress().toString());
        // 回复客户端下线
        channel.writeAndFlush("==>"+sdf.format(new Date())
                +" ["+channel.remoteAddress()+"]"+" 下线！");
    }

    /**
     * channel 活跃
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("==>"+sdf.format(new Date())
                +" ["+channel.remoteAddress()+"]"+" 已经上线！");
    }

    /**
     * channel 不活跃
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("==>"+sdf.format(new Date())
                +" ["+channel.remoteAddress()+"]"+" 已经下线！");
    }

    /**
     * 出现异常会触发该方法 -> 关闭channel
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 关闭
        ctx.close();
    }

}
